/******************************************************************************
 *                       B O M B E R M A N  2 0 1 2
 * 
 * File Name: NetworkHandler.java
 * 
 * COP 4331 Summer 2012 Project
 * 
 * Authors: Trevor Mancuso, Chris Chiarella, Zach Hoyler, Daniel Martin
 * 
 * 
 * Description: Handles all network messages. Decodes and determines what to do
 * when a message from the network is received. Also passes messages to the
 * corresponding socket class.
 * 
 ******************************************************************************/
package bomberman;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.StringTokenizer;
import java.util.logging.Level;
import java.util.logging.Logger;


public class NetworkHandler {
    
    Bomberman game;
    String address;
    
    //Constructor
    NetworkHandler(Bomberman game, String address)
    {
        this.game = game;
        this.address = address;
    }
    
    //When a message is received, determine what to do with it.
    public void handleMessage(String message)
    {
        //level init message. Format: 0(string that is levelSize*levelSize long where 0=no barrier, 1 = destructable barrier, 2 = indestructable barrier)
        if(message.startsWith("0"))
        {
            System.out.println("Got level change packet. Changing level.");
            String level = message.substring(1);
            
            for(int i = 0; i < game.theGame.levelSize; i ++)
            {
                for(int j = 0; j < game.theGame.levelSize; j ++)
                {
                    if(level.charAt((i*game.theGame.levelSize)+j)=='0')
                    {
                        game.theGame.barrierArray[j][i] = null;
                    }
                    if(level.charAt((i*game.theGame.levelSize)+j)=='1')
                    {
                        game.theGame.barrierArray[j][i] = new Barrier(true);
                    }
                    if(level.charAt((i*game.theGame.levelSize)+j)=='2')
                    {
                        game.theGame.barrierArray[j][i] = new Barrier(false);
                    }
                    
                }
            }
            System.out.println("Level change finished");
            
            sendReady();
            
        }
        
        //Movement. Format: "1 x y"
        if(message.startsWith("1"))
        {
            message = message.trim();
            StringTokenizer tokenizer = new StringTokenizer(message.substring(1)," ");
            String xval = tokenizer.nextToken();
            String yval = tokenizer.nextToken();
            int x = Integer.parseInt(xval);
            int y = Integer.parseInt(yval);
            int dir = Integer.parseInt(tokenizer.nextToken());
            
            if(game.host)
            {
                game.bombers[1].moveTo(x,y,dir);
            }
            if(!game.host)
            {
                game.bombers[0].moveTo(x,y,dir);
            }
        }
        //Bomb placing. Format: "2 x y power player"
        if(message.startsWith("2"))
        {
            message = message.trim();
            StringTokenizer tokenizer = new StringTokenizer(message.substring(1)," ");
            int xval = Integer.parseInt(tokenizer.nextToken());
            int yval = Integer.parseInt(tokenizer.nextToken());
            int power = Integer.parseInt(tokenizer.nextToken());
            int playerNum = Integer.parseInt(tokenizer.nextToken());
            
            if(game.host)
            {
                if(playerNum ==2)
                    game.bombers[1].placeBomb();
            }
            if(!game.host)
            {
                if(playerNum==1)
                    game.bombers[0].placeBomb();
            }
            
        }
        //Powerup create. Format "3 x y type"
        if(message.startsWith("3"))
        {
            message = message.trim();
            StringTokenizer tokenizer = new StringTokenizer(message.substring(1)," ");
            int xval = Integer.parseInt(tokenizer.nextToken());
            int yval = Integer.parseInt(tokenizer.nextToken());
            String pType = tokenizer.nextToken();
            pType = pType.trim();
            
            System.out.println("CREATING POWERUP AT: "+xval+" "+yval);
            
            game.theGame.powerupArray[xval][yval] = new Powerup(xval,yval,game, pType);
        }
        if(message.startsWith("4"))
        {
            game.ready = true;
        }
        if(message.startsWith("5"))
        {
            sendLevel();
        }
        if(message.startsWith("6"))
        {
//            message=message.trim();
//            StringTokenizer tokenizer = new StringTokenizer(message.substring(1)," ");
//            String addr = tokenizer.nextToken();
//            
//            game.opAddress = addr;
//            try {
//                System.out.println("Got connection request, client address is: " + InetAddress.getByName(game.opAddress));
//            } catch (UnknownHostException ex) {
//                Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
//            }
            
            game.connected = true;
        }
        
    }
    
    //Send the entire level to the client.
    public void sendLevel()
    {
        String message = "0";
        
        for(int i=0; i < game.theGame.levelSize; i++)
        {
            
            
            for(int j = 0; j < game.theGame.levelSize; j ++)
            {
                if(game.theGame.getBarrier(i, j)==null)
                    message= message+"0";
                else if(game.theGame.getBarrier(i, j).isDestructable)
                    message=message+"1";
                else if(!game.theGame.getBarrier(i, j).isDestructable)
                    message=message+"2";
            }
            
        }
        
        try
            {
                game.socket.sendMessage(message, address);
            } catch (UnknownHostException ex)
            {
                Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IOException ex)
            {
                Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
            }
        
    }
    
    //Send a move packet
    public void sendMove(int xPos, int yPos, int direction)
    {
        String message = "1 "+xPos+" "+yPos+" "+direction;
        try
        {
            game.socket.sendMessage(message, address);
        } catch (UnknownHostException ex)
        {
            Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex)
        {
            Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    //Send a new bomb packet
    public void sendBomb(int xPos, int yPos, int pow, int playerNum)
    {
        String message = "2"+" "+xPos+" "+yPos+" "+pow+" "+playerNum;
        try
        {
            game.socket.sendMessage(message, address);
        } catch (UnknownHostException ex)
        {
            Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex)
        {
            Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    //Send a new powerup packet
    public void sendPowerup(int xPos, int yPos, Powerup.Type type)
    {
        String message = "3"+" "+xPos+" "+yPos+" "+type;
        try
        {
            game.socket.sendMessage(message, address);
        } catch (UnknownHostException ex)
        {
            Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex)
        {
            Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    //Signal that the client is ready to start a game.
    public void sendReady()
    {
        String message = "4";
        try
        {
            game.socket.sendMessage(message, address);
            game.ready = true;
        } catch (UnknownHostException ex)
        {
            Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex)
        {
            Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    //request the level from the server
    public void requestLevel()
    {
        String message = "5";
        try
        {
            game.socket.sendMessage(message, address);
        } catch (UnknownHostException ex)
        {
            Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex)
        {
            Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    //request a connection to the server
    public void requestConnection()
    {
        String ipAddr;
        try {
            ipAddr = InetAddress.getLocalHost().getHostAddress();
            String message = "6" + " "+ ipAddr;
            
            System.out.println("Requesting connection on "+ message);

            game.socket.sendMessage(message, address);
             
            
        } catch (UnknownHostException ex) {
            Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
                Logger.getLogger(NetworkHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
        
                

    }
    
}
